﻿Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Controls.Primitives
Imports System.Windows.Documents
Imports System.Windows.Media
Imports System.Collections.Generic
Imports System.Windows.Media.Media3D

Public Class ResizeThumb
    Inherits Thumb

    'Private rotateTransform As RotateTransform
    'Private angle As Double
    'Private adorner As Adorner
    'Private transformOrigin As Point
    Private designerItem As ContentPresenter

    Public Sub New()

        AddHandler Me.DragStarted, AddressOf Me.ResizeThumb_DragStarted
        AddHandler Me.DragDelta, AddressOf Me.ResizeThumb_DragDelta
        AddHandler Me.DragCompleted, AddressOf Me.ResizeThumb_DragCompleted
        AddHandler Me.DataContextChanged, AddressOf Me.DataContext_Changed

    End Sub

    Public Sub DataContext_Changed(ByVal sender As Object, ByVal e As DependencyPropertyChangedEventArgs)
        'Dim t As String = "tot"
    End Sub

    Private Sub ResizeThumb_DragStarted(ByVal sender As Object, ByVal e As DragStartedEventArgs)

        Me.designerItem = FindCanvasChild(Me)

        'On vérifie que la taille du designerItem n'est pas calculée automatiquement
        If Me.designerItem IsNot Nothing Then
            If Double.IsNaN(designerItem.Height) Then designerItem.Height = designerItem.ActualHeight
            If Double.IsNaN(designerItem.Width) Then designerItem.Width = designerItem.ActualWidth
        End If

        'If (Me.designerItem IsNot Nothing) Then

        'Me.canvas = DirectCast(VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(Me.designerItem)), Canvas)

        '        If (Me.canvas IsNot Nothing) Then

        '            Me.transformOrigin = Me.designerItem.RenderTransformOrigin
        '            Me.rotateTransform = DirectCast(Me.designerItem.RenderTransform, RotateTransform)

        '            If (Me.rotateTransform IsNot Nothing) Then
        '                Me.angle = Me.rotateTransform.Angle * Math.PI / 180.0
        '            Else
        '                Me.angle = 0D
        '            End If

        '            Dim adornerLayer As AdornerLayer = adornerLayer.GetAdornerLayer(Me.canvas)
        '            If (adornerLayer IsNot Nothing) Then
        '                Me.adorner = New SizeAdorner(Me.designerItem)
        '                adornerLayer.Add(Me.adorner)
        '            End If

        '        End If

        'End If

    End Sub

    Private Sub ResizeThumb_DragDelta(ByVal sender As Object, ByVal e As DragDeltaEventArgs)

        If (Me.designerItem IsNot Nothing) Then

            Dim deltaVertical, deltaHorizontal As Double

            Select Case VerticalAlignment

                Case System.Windows.VerticalAlignment.Bottom
                    deltaVertical = Math.Min(-e.VerticalChange, designerItem.ActualHeight - designerItem.MinHeight)
                    'canvas.SetTop(Me.designerItem, canvas.GetTop(Me.designerItem) + (Me.transformOrigin.Y * deltaVertical * (1 - Math.Cos(-Me.angle))))
                    'canvas.SetLeft(Me.designerItem, canvas.GetLeft(Me.designerItem) - deltaVertical * Me.transformOrigin.Y * Math.Sin(-Me.angle))
                    'Modifier également l'élément du dessus
                    Me.designerItem.Height -= deltaVertical

                Case System.Windows.VerticalAlignment.Top
                    deltaVertical = Math.Min(e.VerticalChange, Me.designerItem.ActualHeight - Me.designerItem.MinHeight)
                    canvas.SetTop(designerItem, canvas.GetTop(designerItem) + deltaVertical)
                    'canvas.SetTop(Me.designerItem, canvas.GetTop(Me.designerItem) + deltaVertical * Math.Cos(-Me.angle) + (Me.transformOrigin.Y * deltaVertical * (1 - Math.Cos(-Me.angle))))
                    'canvas.SetLeft(Me.designerItem, canvas.GetLeft(Me.designerItem) + deltaVertical * Math.Sin(-Me.angle) - (Me.transformOrigin.Y * deltaVertical * Math.Sin(-Me.angle)))
                    Me.designerItem.Height -= deltaVertical

                Case Else
            End Select

            Select Case HorizontalAlignment
                Case System.Windows.HorizontalAlignment.Left
                    deltaHorizontal = Math.Min(e.HorizontalChange, Me.designerItem.ActualWidth - Me.designerItem.MinWidth)
                    'Canvas.SetTop(Me.designerItem, Canvas.GetTop(Me.designerItem) + deltaHorizontal * Math.Sin(Me.angle) - Me.transformOrigin.X * deltaHorizontal * Math.Sin(Me.angle))
                    'Canvas.SetLeft(Me.designerItem, Canvas.GetLeft(Me.designerItem) + deltaHorizontal * Math.Cos(Me.angle) + (Me.transformOrigin.X * deltaHorizontal * (1 - Math.Cos(Me.angle))))
                    canvas.SetLeft(designerItem, canvas.GetLeft(designerItem) + deltaHorizontal)
                    Me.designerItem.Width -= deltaHorizontal
                Case System.Windows.HorizontalAlignment.Right
                    deltaHorizontal = Math.Min(-e.HorizontalChange, Me.designerItem.ActualWidth - Me.designerItem.MinWidth)
                    'Canvas.SetTop(Me.designerItem, Canvas.GetTop(Me.designerItem) - Me.transformOrigin.X * deltaHorizontal * Math.Sin(Me.angle))
                    'Canvas.SetLeft(Me.designerItem, Canvas.GetLeft(Me.designerItem) + (deltaHorizontal * Me.transformOrigin.X * (1 - Math.Cos(Me.angle))))
                    Me.designerItem.Width -= deltaHorizontal
                Case Else
            End Select
        End If

        e.Handled = True
    End Sub

    Private Sub ResizeThumb_DragCompleted(ByVal sender As Object, ByVal e As DragCompletedEventArgs)
        'If (Me.adorner IsNot Nothing) Then

        '    Dim adornerLayer As AdornerLayer = adornerLayer.GetAdornerLayer(Me.canvas)
        '    If (adornerLayer IsNot Nothing) Then adornerLayer.Remove(Me.adorner)

        '    Me.adorner = Nothing
        'End If
    End Sub

    ''' <summary>
    ''' Parcourt l'arbre visuel à partir de l'élément depObj en recherchant un UIElement
    ''' enfant direct d'un Canvas. Si un tel élément n'est pas trouvé, la fonction renvoie Noting.
    ''' </summary>
    ''' <param name="depObj">
    ''' Un DependencyObject à partir duquelle la recherche débute.
    ''' </param>
    Public Function FindCanvasChild(ByVal depObj As DependencyObject) As UIElement

        While depObj IsNot Nothing

            'Dim elem As UIElement = TryCast(depObj, UIElement)

            ' VisualTreeHelper works with objects of type Visual or Visual3D.
            ' If the current object is not derived from Visual or Visual3D,
            ' then use the LogicalTreeHelper to find the parent element.
            If (TypeOf depObj Is Visual) Or (TypeOf depObj Is Visual3D) Then
                If TypeOf (VisualTreeHelper.GetParent(depObj)) Is Canvas Then
                    Exit While
                Else
                    depObj = VisualTreeHelper.GetParent(depObj)
                End If
            Else
                If TypeOf (LogicalTreeHelper.GetParent(depObj)) Is Canvas Then
                    Exit While
                Else
                    depObj = LogicalTreeHelper.GetParent(depObj)
                End If
            End If

        End While

        Return TryCast(depObj, UIElement)

    End Function

End Class
